package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl;

import com.iwhalecloud.citybrain.flow.platform.manager.domain.gateway.http.EventCallGateway;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.eventconfig.DeployedEventConfigDomain;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowEventConfigRepository;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * 公共的任务事件处理器
 * 前置/后置事件中的通用操作，提取出来复用，方便后面扩展
 * @author songxianfeng
 * @date 2021/07/09
 */

@Slf4j
@Component
public class CommonTaskEventProcessor {
    @Lazy
    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private FlowEventConfigRepository eventConfigRepository;

    @Lazy
    @Autowired
    private TaskService taskService;

    @Lazy
    @Autowired
    private RuntimeService runtimeService;

    /**
     * 根据类型查询所有事件
     * @param taskEntity 当前执行到到任务实体
     * @param taskType 事件的类型
     * @return 事件列表
     */
    public List<DeployedEventConfigDomain> resolveEventConfigList(TaskEntity taskEntity, String taskType) {
        String deploymentId = resolveDeploymentId(taskEntity.getProcessDefinitionId());
        if(null==deploymentId){
            return null;
        }
        return eventConfigRepository.getEventConfigList(deploymentId,
                taskEntity.getTaskDefinitionKey(),
                taskType);
    }


    public List<DeployedEventConfigDomain> resolveEventConfigList(String processInstanceId,String nodeCode, String taskType) {
        String processDefinitonId = resolveProcessDefinitonId(processInstanceId);
        String deploymentId = resolveDeploymentId(processDefinitonId);
        return eventConfigRepository.getEventConfigList(deploymentId,
                nodeCode,
                taskType);
    }

    private String resolveProcessDefinitonId(String processInstanceId){
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if (Objects.nonNull(processInstance)){
            return processInstance.getProcessDefinitionId();
        }
        return null;
    }

    /**
     * 根据类型查询所有事件
     * @param activityEvent 当前执行到到执行实体
     * @param activityType 事件的类型
     * @return 事件列表
     */
    public List<DeployedEventConfigDomain> resolveEventConfigList(FlowableActivityEventImpl activityEvent, String activityType) {
        String deploymentId = resolveDeploymentId(activityEvent.getProcessDefinitionId());
        return eventConfigRepository.getEventConfigList(deploymentId,
                activityEvent.getActivityId(),
                activityType);
    }


        /**
         * 根据流程定义id查询部署id
         * @param processDefinitionId 流程定义id
         * @return 查询部署id
         */
    public String resolveDeploymentId(String processDefinitionId) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
                processDefinitionId(processDefinitionId).singleResult();
        if(null==processDefinition){
            return null;
        }
        return processDefinition.getDeploymentId();
    }

    /**
     * 判断是否符合URL的格式
     * @param url 原url
     * @return true：符合；false：不符合
     */
    public static boolean isUrl(String url) {
        final String REGEX_URL = "(https?)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]";
        return Pattern.matches(REGEX_URL, url);
    }


}
